//------------------------------------------------------------
//  Filename: tcdm_lint_connect.sv
//   
//  Author  : wlduan@ucchip.com
//  Revise  : 2019-10-16 15:51
//  Description: 
//   
//  Copyright (C) 2019, UCCHIP, Inc. 					      
//  All Rights Reserved.                                       
//-------------------------------------------------------------
//

`timescale 1ns/1ps 

module tcdm_lint_apb #(
    parameter DATA_WIDTH = 32,
    parameter ADDR_WIDTH = 32
)(
    input  logic   clk,
    input  logic   rst_n,

	LINT_IF.Slave   lint_slave ,
	APB_IF.Master   apb_master
);
//-------------------------------------------------------
enum logic[1:0] {IDLE, WAIT_READY,DISPATCH_DATA} cs,ns;
//-------------------------------------------------------
always_ff @(posedge clk,negedge rst_n) begin
    if(rst_n == 0)begin 
        cs <= IDLE; 
    end 
    else begin 
        cs <= ns; 
    end 
end 
//-------------------------------------------------------------
always_comb begin
    ns = cs;
    case(cs)
        IDLE: begin
            if(lint_slave.data_req) begin
                ns = WAIT_READY;
            end
        end
        WAIT_READY: begin
            if(apb_master.pready) begin 
                ns = DISPATCH_DATA;
            end
        end
        DISPATCH_DATA: begin
            ns = IDLE;
        end
    endcase
end
//-------------------------------------------------------
assign lint_slave.data_gnt = (ns == DISPATCH_DATA); 
//-------------------------------------------------------
always_comb begin 
    apb_master.penable = '0;
    apb_master.psel    = '0;
    apb_master.paddr   = '0;
    apb_master.pwdata  = '0;
    apb_master.pwrite  = '0;
    if ((cs == WAIT_READY)||((cs == IDLE)&lint_slave.data_req)) begin
        apb_master.penable = 1'b1;
        apb_master.psel    = 1'b1;
        apb_master.paddr   = lint_slave.data_addr;
        apb_master.pwdata  = lint_slave.data_wdata;
        apb_master.pwrite  = lint_slave.data_we;
    end 
end 
//-------------------------------------------------------
logic [ DATA_WIDTH-1:0] rdata_q;
logic                   ropc_q;
logic                   rvld_q;
//-------------------------------------------------------
always @(posedge clk,negedge rst_n) begin
    if(rst_n == 1'b0) begin 
        rdata_q  <= 'b0;
        ropc_q   <= 'b0;
        rvld_q   <= 'b0;
    end 
    else if (ns == DISPATCH_DATA) begin
        rdata_q  <= apb_master.prdata;
        ropc_q   <= apb_master.pslverr;
        rvld_q   <= 1'b1;
    end 
    else begin
        rvld_q   <= 1'b0;
    end
end 
//-------------------------------------------------------
always @(posedge clk,negedge rst_n) begin
    if(rst_n == 1'b0) begin 
        lint_slave.data_r_rdata <= 'b0;
        lint_slave.data_r_opc   <= 'b0;
        lint_slave.data_r_valid <= 'b0;
    end 
    else  begin
        lint_slave.data_r_rdata <= rdata_q;
        lint_slave.data_r_opc   <= ropc_q;
        lint_slave.data_r_valid <= rvld_q;
    end
end 

endmodule  
